/**
 * @Author: lena
 * @Description:
 * @Version: 1.0.0
 * @Date: 2021/8/24 21:54
 */

package datatype

import "fmt"

// Map1 初始化
func Map1() {
	// 方式一 : 已知所需多少空间 在使用前分配
	var map1 map[string]string
	if map1 == nil {
		fmt.Println("map1 is null") // map1 is null
	}
	// 使用前必须先分配空间 否则会报错：panic: assignment to entry in nil map
	map1 = make(map[string]string, 3)
	map1["a"] = "111"
	map1["b"] = "222"
	map1["c"] = "333"
	fmt.Printf("%d,%v\n", len(map1), map1) // 3,map[a:111 b:222 c:333]

	// 方式二 : 不声明空间的大小 但在初始化的时候输入元素
	map2 := map[string]string{
		"a": "111",
		"b": "222",
		"c": "333", // 即使是最后一个也必须用","
	}
	// 之后也可以再添加
	map2["d"] = "444"
	fmt.Println(map2) // map[a:111 b:222 c:333 d:444]

	// 方式三 : 不声明大小 由系统自动分配
	map3 := make(map[string]string)
	map3["a"] = "111"
	map3["b"] = "222"
	map3["c"] = "333"
	fmt.Println(map3) // map[a:111 b:222 c:333]
}

func Map2() {
	// 初始化
	map1 := make(map[string]string)
	map1["a"] = "111"
	map1["b"] = "222"
	map1["c"] = "333"
	// 遍历
	for index, value := range map1 {
		fmt.Println(index, value)
	}
	// 增加
	map1["d"] = "444"
	fmt.Println(map1) // map[a:111 b:222 c:333 d:444]
	// 修改
	map1["a"] = "aaa"
	fmt.Println(map1) // map[a:111 b:222 c:333 d:444]
	// 删除
	delete(map1, "b")
	fmt.Println(map1) // map[a:aaa c:333 d:444]
}

func Map3() {
	// 初始化
	map1 := make(map[string]string)
	map1["a"] = "111"
	map1["b"] = "222"
	map1["c"] = "333"
	fmt.Println(map1) // map[a:111 b:222 c:333]
	method4(map1)
	fmt.Println(map1) // map[a:aaa b:222 c:333]
}

func method4(map1 map[string]string) {
	map1["a"] = "aaa"
}

// Map4 删除元素
func Map4() {
	map1 := make(map[string]string)
	map1["a"] = "111"
	map1["b"] = "222"
	map1["c"] = "333"
	fmt.Println(map1)
	// 删除一个存在的元素
	delete(map1, "a")
	fmt.Println(map1)
	// 删除一个不存在的元素:不会报错
	delete(map1, "d")
	fmt.Println(map1)
}

// Map5 map使用切片作为value
func Map5() {
	m := map[int][]int{}
	arr := []int{2, 3, 4, 5, 6}
	m[1] = arr
	fmt.Println(m) // map[1:[2 3 4 5 6]]
	m[1][2] = 44
	fmt.Println(m) // map[1:[2 3 44 5 6]]
	// m[2][1]=34	// panic: runtime error: index out of range [1] with length 0
	m[2] = []int{}
	// m[2][1]=2	// panic: runtime error: index out of range [1] with length 0
	fmt.Println(m) // map[1:[2 3 44 5 6] 2:[]]
}

// Map6 测试map存储是否按顺序
func Map6() {
	// 结论：按key值顺序排序
	m := map[int]int{
		4: 1,
		3: 2,
		6: 3,
		1: 4,
		0: 3,
	}
	fmt.Println(m) // map[0:3 1:4 3:2 4:1 6:3]
	m1 := map[string]int{
		"abc":    3,
		"k":      2,
		"bcd":    2,
		"c":      1,
		"wer":    1,
		"defrgd": 1,
		"ef":     1,
		"f":      1,
	}
	fmt.Println(m1) // map[abc:3 bcd:2 c:1 defrgd:1 ef:1 f:1 k:2 wer:1]
}

// testChange map是引用类型，修改引用类型的值，会直接修改原来的map
func testChange(m map[int]int) {
	m[0] = 100
	m[1] = 1000
}
func Map7() {
	m := map[int]int{1: 1, 2: 2, 3: 3}
	fmt.Println(m) // map[1:1 2:2 3:3]
	testChange(m)
	fmt.Println(m) // map[0:100 1:1000 2:2 3:3]
}

// Map8 判断map中某一key是否存在
func Map8() {
	m := map[int]int{1: 1}
	fmt.Println(m[2])  // 0
	i, ok := m[2]      // ok=false,表示不存在
	fmt.Println(ok, i) // false 0
}

// Map9 遍历获取map所有元素
func Map9() {
	maps := map[string]string{
		"lena":  "7777",
		"study": "good",
		"age":   "1",
		"hello": "world",
	}
	for key, value := range maps {
		fmt.Printf("%s:%s\n", key, value)
	}
}
